/*
 *  LinearModule.c
 *  
 *
 *  Created by Thomas Fu on 6/9/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "LinearModule.h"
#include <iostream>
using namespace std;

void initializeLinearModule(LinearModule *lm)
{
	lm->inputHistory = (double*)malloc(sizeof(double) * lm->order * 4);
	lm->inputWeights = lm->inputHistory + lm->order;
	lm->outputHistory = lm->inputWeights + lm->order;
	lm->outputWeights = lm->outputHistory + lm->order;
	for(int i = 0; i < lm->order; i++)
	{
		lm->inputHistory[i] = 0;
		lm->outputHistory[i] = 0;
	}
	lm->oldestBufferEntry = 0;
}


void intializeLinearModule(LinearModule *lm, double *iWeights, double *oWeights)
{
	initializeLinearModule(lm);
	memcpy(lm->inputWeights, iWeights, sizeof(double) * lm->order);
	memcpy(lm->outputWeights, oWeights, sizeof(double) * lm->order);
}

double advanceModule(LinearModule *lm, double val)
{
  double numSum = lm->inputWeights[0]  * val;
  double denSum = 0;
	
	int i, curLookup;
  for(i = 0; i < lm->order-1; i++)
	{
		curLookup = (lm->oldestBufferEntry + 1 + i) % lm->order;
		numSum += lm->inputWeights[i+1] * lm->inputHistory[curLookup]; 
		denSum += lm->outputWeights[i+1] * lm->outputHistory[curLookup];
	}
  lm->inputHistory[lm->oldestBufferEntry] = val;
  lm->outputHistory[lm->oldestBufferEntry] = 1 / (lm->outputWeights[0]) * (numSum - denSum);
	
  lm->oldestBufferEntry = (lm->oldestBufferEntry+1) % lm->order;
	
  return lm->outputHistory[lm->oldestBufferEntry];
}
